﻿using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

namespace W
{
    public class TcpServer
    {
        public event EventHandler<SocketClientEventArgs> ClientAccepted;
        protected virtual void OnClientAccepted(SocketClientEventArgs e)
        {
            if (ClientAccepted != null) ClientAccepted(this, e);
        }

        private bool _keepRunning;
        private Socket _socket;
        public int Port { get; private set; }
        public bool IsRunning { get; private set; }

        public TcpServer(int port)
        {
            Port = port;
        }
        public void Start()
        {
            if (IsRunning) return;
            IsRunning = true;
            _keepRunning = true;
            new Thread(AcceptClient) { IsBackground = true }.Start();
        }
        private void CloseSocket()
        {
            if (_socket == null) return;
            _socket.Close();
            _socket = null;
        }
        private void AcceptClient()
        {
            CloseSocket();
            _socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp) {Blocking = false};
            _socket.Bind(new IPEndPoint(IPAddress.Any, Port));
            _socket.Listen(64);
            while (_keepRunning)
            {
                if (!_socket.Poll(1000, SelectMode.SelectRead))
                    continue;
                try
                {
                    var client = _socket.Accept();
                    OnClientAccepted(new SocketClientEventArgs(client));
                }
                catch
                {
                    Thread.Sleep(1000);
                }
            }
            CloseSocket();
            IsRunning = false;
        }
        public void Stop()
        {
            _keepRunning = false;
        }
    }
}